/*
 * Tencent is pleased to support the open source community by making QMUI_Android available.
 *
 * Copyright (C) 2017-2018 THL A29 Limited, a Tencent company. All rights reserved.
 *
 * Licensed under the MIT License (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 *
 * http://opensource.org/licenses/MIT
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.allenlee.mvphelper.base;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;

import com.allenlee.mvphelper.R;
import com.allenlee.mvphelper.activity.MHMainActivity;
import com.allenlee.mvphelper.bean.MHItemDescription;
import com.allenlee.mvphelper.manager.MHDataManager;
import com.allenlee.mvphelper.util.NavigationHelper;
import com.allenlee.mvphelper.util.ToastHelper;
import com.qmuiteam.qmui.arch.QMUIFragment;
import com.qmuiteam.qmui.arch.SwipeBackLayout;
import com.qmuiteam.qmui.util.QMUIDisplayHelper;
import com.qmuiteam.qmui.util.QMUIViewHelper;
import com.qmuiteam.qmui.widget.QMUITopBar;
import com.qmuiteam.qmui.widget.QMUITopBarLayout;
import com.qmuiteam.qmui.widget.dialog.QMUIDialog;
import com.qmuiteam.qmui.widget.dialog.QMUIDialogAction;
import com.qmuiteam.qmui.widget.dialog.QMUITipDialog;
import com.tbruyelle.rxpermissions2.RxPermissions;
import com.uber.autodispose.AutoDispose;
import com.uber.autodispose.AutoDisposeConverter;
import com.uber.autodispose.android.lifecycle.AndroidLifecycleScopeProvider;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.Lifecycle;
import butterknife.ButterKnife;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;

/**
 * Created by lifei on 2018/1/7.
 */
public abstract class BaseFragment<P extends IBasePresenter> extends QMUIFragment implements IBaseView {

    protected String TAG = BaseFragment.class.getSimpleName();
    protected Activity mActivity;
    private QMUITipDialog mLoadingDialog;

    protected P mPresenter;
    private Disposable mDisposable;

    protected abstract void beforeInitView();

    // 抽象方法，子类返回布局id
    protected abstract int getLayout();

    protected abstract void initTopbar();

    protected abstract void initView();

    protected abstract P setPresenter();

    protected abstract void afterSetPresenter();

    public BaseFragment() {
    }

    @Override
    protected int backViewInitOffset(Context context, int dragDirection, int moveEdge) {
        if (moveEdge == SwipeBackLayout.EDGE_TOP || moveEdge == SwipeBackLayout.EDGE_BOTTOM) {
            return 0;
        }
        return QMUIDisplayHelper.dp2px(context, 100);
    }

    // 页面切换效果
    @Override
    public TransitionConfig onFetchTransitionConfig() {
        return SLIDE_TRANSITION_CONFIG;
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        TAG = this.getClass().getSimpleName();
        Log.i(TAG, "onAttach: ");
        this.mActivity = (Activity) context;
    }

    @Override
    protected View onCreateView() {
        Log.i(TAG, "onCreateView: ");
        beforeInitView();
        View view = LayoutInflater.from(getActivity()).inflate(getLayout(), null);
        ButterKnife.bind(this, view);
        initTopbar();
        initView();
        // 实例化和绑定 P 层
        mPresenter = setPresenter();
        if (mPresenter != null && !mPresenter.isAttached()) {
            mPresenter.attach(this);
        }
        afterSetPresenter();
        return view;
    }

    @Override
    public void onResume() {
        super.onResume();
        Log.i(TAG, "onResume: ");
    }

    protected void goToWebExplorer(@NonNull String url, @Nullable String title) {
        Intent intent = MHMainActivity.createWebExplorerIntent(getContext(), url, title);
        startActivity(intent);
    }

    protected void injectDocToTopBar(QMUITopBar topBar) {
        final MHItemDescription description = MHDataManager.getInstance().getDescription(this.getClass());
        if (description != null) {
            topBar.addRightTextButton("DOC", QMUIViewHelper.generateViewId())
                .setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        goToWebExplorer(description.getDocUrl(), description.getName());
                    }
                });
        }
    }

    protected void injectDocToTopBar(QMUITopBarLayout topBar) {
        final MHItemDescription description = MHDataManager.getInstance().getDescription(this.getClass());
        if (description != null) {
            topBar.addRightTextButton("DOC", QMUIViewHelper.generateViewId())
                .setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        goToWebExplorer(description.getDocUrl(), description.getName());
                    }
                });
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        Log.i(TAG, "onPause: ");
    }

    @Override
    public void onStop() {
        super.onStop();
        Log.i(TAG, "onStop: ");
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        Log.i(TAG, "onDestroyView: ");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i(TAG, "onDestroy: ");
        if (mDisposable != null && !mDisposable.isDisposed()) {
            mDisposable.dispose();
        }

        // 解绑，避免内存泄漏
        if (mPresenter != null) {
            mPresenter.detach();
            mPresenter = null;
        }
    }

    @Override
    public Context getContext() {
        return mActivity;
    }

    /**
     * 绑定生命周期 防止MVP内存泄漏
     * @param <T>
     * @return
     */
    @Override
    public <T> AutoDisposeConverter<T> bindAutoDispose() {
        return AutoDispose.autoDisposable(AndroidLifecycleScopeProvider
            .from(this, Lifecycle.Event.ON_DESTROY));
    }

    protected void requestPermissions(String... permissions) {
        RxPermissions rxPermissions = new RxPermissions(this);
        mDisposable = rxPermissions
            .requestEachCombined(permissions)
            .subscribe(permission -> { // will emit 1 Permission object
                if (permission.granted) {
                    permissionGranted();
                } else if (permission.shouldShowRequestPermissionRationale) {
                    // At least one denied permission without ask never again
                    permissionDenied();
                } else {
                    // At least one denied permission with ask never again
                    // Need to go to the settings
                    showLongMessageDialog();
                    permissionDenied();
                }
            }, new Consumer<Throwable>() {
                @Override
                public void accept(Throwable throwable) throws Exception {
                    showToast("onError");
                    throwable.printStackTrace();
                }
            });
    }

    private void showLongMessageDialog() {
        QMUIDialog qmuiDialog = new QMUIDialog.MessageDialogBuilder(mActivity)
            .setTitle("权限申请")
            .setMessage("当前应用缺少必要权限。\n\n请点击\"去授权\"-\"权限\"-打开所需权限。")
            .addAction("拒绝", new QMUIDialogAction.ActionListener() {
                @Override
                public void onClick(QMUIDialog dialog, int index) {
                    dialog.dismiss();
                }
            })
            .addAction("去授权", new QMUIDialogAction.ActionListener() {
                @Override
                public void onClick(QMUIDialog dialog, int index) {
                    dialog.dismiss();
                    NavigationHelper.startAppSettings(mActivity);
                }
            })
            .create(R.style.QMUI_Dialog);
        qmuiDialog.setCancelable(false);
        qmuiDialog.show();
    }

    @Override
    public void permissionGranted() {
        // 处理权限被允许
    }

    @Override
    public void permissionDenied() {
        // 处理权限被拒绝
    }

    public void showToast(String msg) {
        ToastHelper.showToast(getContext(), msg);
    }

    public void showToast(int msgId) {
        ToastHelper.showToast(getContext(), msgId);
    }

    public void showLongToast(String msg) {
        ToastHelper.showLongToast(getContext(), msg);
    }

    public void showLongToast(int msgId) {
        ToastHelper.showLongToast(getContext(), msgId);
    }

    public void showLoading(String text) {
        if (mLoadingDialog == null) {
            mLoadingDialog = new QMUITipDialog.Builder(getContext())
                .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
                .setTipWord(text)
                .create();
        }
        if (!mLoadingDialog.isShowing()) {
            mLoadingDialog.show();
        }
    }

    public void hideLoading() {
        if (mLoadingDialog != null && mLoadingDialog.isShowing()) {
            mLoadingDialog.dismiss();
        }
    }
}
